import { transName } from "./utils";
import compService from "@gd-accbuild-core/components/gd-accbuild-ui/gd-ui/gd-service";
import type { App } from "vue";
export const routerViewConfig = {
  Layout: () => Promise.resolve(),
  middleLayout: () => Promise.resolve(),
  PageSearchformTablelistSimple: () => Promise.resolve(),
};
interface GlobalService {
  toast: any;
  loading: any;
  container: any;
}
interface ApiResponse {
  code: number;
  msg: string;
  data: any;
  [propname: string]: any;
}
interface GlobalConfig {
  targetPlatform: "pc-admin" | "mobile";
  store: any;
  router: any;
  ROUTER_MODE: "history" | "hash";
  pagesLayout: Array<Object>;
  getMetaListByVmCode: () => Promise<ApiResponse>;
  getResourceList: () => Promise<ApiResponse>;
  get: (arg: { vmCode: string; params: Object }) => Promise<ApiResponse>;
  getList: (arg: { vmCode: string; params: Object }) => Promise<ApiResponse>;
  deleteBatch: (arg: { vmCode: string; params: Object }) => Promise<ApiResponse>;
  save: (arg: { vmCode: string; data: Object }) => Promise<ApiResponse>;
  update: (arg: { vmCode: string; data: Object }) => Promise<ApiResponse>;
  compService: GlobalService;
  [propname: string]: any;
}
export const globalConfig: GlobalConfig = {
  BASE_ROUTER_PREFIX_PATH: "",
  BASE_STATIC_PREFIX_PATH: "",
  ROUTER_MODE: "history",
  enableServerless: true,
  targetPlatform: "pc-admin",
  pagesLayout: [],
  isSuccessReqBackend: function (res: ApiResponse) {
    return res.code === 0;
  },
  getErrorMsgReqBackend: function (res: ApiResponse) {
    return res.msg;
  },
  getBackendDataItems: function (res: ApiResponse) {
    if (this.isSuccessReqBackend(res)) {
      return res.data.items;
    } else {
      return [];
    }
  },
  getBackendData: function (res: ApiResponse) {
    if (this.isSuccessReqBackend(res)) {
      return res.data.data;
    } else {
      return {};
    }
  },
  fakerReqBackend: async function () {
    return Promise.resolve({
      code: 0,
      data: {
        data: {},
        items: [],
      },
    });
  },
  store: null, //全局store
  router: null, //全局router
  /**
   * 获取元数据,用于表头、表单 配置
   */
  getMetaListByVmCode: async () => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  /**
   * 获取所有的资源
   * 用于pagesJsonAutoGen.js
   */
  getResourceList: async () => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  /**
   * 实体的增删改查接口
   * params={id,}
   */
  get: async ({ vmCode, params }) => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  /**
   * 实体的增删改查接口
   * params={isPaged,pageNum,pageSize}
   */
  getList: async ({ vmCode, params }) => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  /**
   * 实体的增删改查接口
   */
  deleteBatch: async ({ vmCode, params }) => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  /**
   * 实体的增删改查接口
   */
  save: async ({ vmCode, data }) => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  /**
   * 实体的增删改查接口
   */
  update: async ({ vmCode, data }) => {
    return {
      code: -1,
      msg: "接口不存在",
      data: {},
    };
  },
  compService,
};
export const resourceApiAliasConfig = {
  resourceUrlKeyAlias: "route", // 地址栏显示的路径//route
  childrenKeyAlias: "children", // 树形的子成员数组的key//children
  realPageFileKeyAlias: "pagePath", // 用于映射真实页面文件的key//pagePath
  resourceTypeKeyAlias: "resourceType", // 资源类型的key//resourceType
  resourcePermsKeyAlias: "code", // 权限代码的key//code
  resourceNameAlias: "name",
  resourceIconAlias: "icon",
  targetKeyAlias: "target", //按钮是弹窗、新页面(_blank)
  targetResourcePermsKeyAlias: "targetResourcePermsCode", //跳转目标的权限code
  idKeyAlias: "id",
  pidKeyAlias: "parentId", // kebabPidAlias必须与pidKeyAlias对应
  kebabPidAlias: "parent-id", // kebabPidAlias必须与pidKeyAlias对应
  hasChildrenAlias: "hasChildren", // 后端返回的树形数据中不能使用,仅用于前端懒加载
  kebabHasChildrenAlias: "has-children",
  ordinalKeyAlias: "ordinal", //资源数组拼接树时排序使用
  isEnableKeyAlias: "isEnable",
  kebabIsEnableKeyAlias: "is-enable",
  uiOptionsKeyAlias: "uiOptions",
  /////////////////////////////////////
  //uiOptions里的字段
  pageUiTemplateConfigsKeyAlias: "pageUiTemplateConfigs",
  pageLayoutConfigKeyAlias: "pageLayoutConfig",
  /////////////////////////////////////
  //视图模型里的字段
  viewModel_field_fieldNameAlias: "propCode", //对应DTO的字段
  /////视图模型里的 uiOptions里的子字段 开始
  //用于getColumns里的uiOptions
  viewModel_field_uiOptions_searchFormItemUiConfigAlias: "searchFormItemUiConfig",
  viewModel_field_uiOptions_searchFormDataWatcherFuncAlias: "searchFormDataWatcherFunc", //搜索表单当前字段值改变触发的联动事件
  viewModel_field_uiOptions_tableColUiConfigAlias: "tableColUiConfig",
  viewModel_field_uiOptions_tableCellDataWatcherFuncAlias: "tableCellDataWatcherFunc", //表格的单元格值改变触发的联动事件
  viewModel_field_uiOptions_containerFormItemUiConfigAlias: "containerFormItemUiConfig",
  viewModel_field_uiOptions_containerFormDataWatcherFuncAlias: "containerFormDataWatcherFunc", //容器表单当前字段值改变触发的联动事件
  vmConfigAlias: "dynmicComponentConfig",
  /////视图模型里的 uiOptions里的子字段 结束
};

/**
 * code编码规则;后端返回时的规则;且VmCode表名必须是分割后的最后一个字符串
 */
export const resourcePermsKeyDefinedRule = {
  namedType: "Pascal",
  splitStr: ".",
  //内建按钮信息
  buildInBtnInfo: {
    //添加按钮
    Create: {
      MetaKey: "form-create-above-table", //按钮组件的元数据key
      CodeSuffix: "Create", //Code后缀
      DefaultTextVal: "新增",
    },
    //添加子节点
    CreateChildNode: {
      MetaKey: "table-create-child-node-btn", //按钮组件的元数据key
      CodeSuffix: "CreateChildNode", //Code后缀
      DefaultTextVal: "添加子节点",
    },
    //批量删除
    BatchDelete: {
      MetaKey: "form-batch-delete-above-table",
      CodeSuffix: "BatchDelete",
      DefaultTextVal: "批量删除",
    },
    //表格上方的查询按钮
    Search: {
      MetaKey: "form-get-list-above-table",
      CodeSuffix: "GetList",
      DefaultTextVal: "查询",
    },
    //单行删除
    Delete: {
      MetaKey: "table-delete-btn",
      CodeSuffix: "Delete",
      DefaultTextVal: "删除",
    },
    //单行编辑
    Update: {
      MetaKey: "table-update-btn",
      CodeSuffix: "Update",
      DefaultTextVal: "编辑",
    },
    //单行查看详情
    GetInfo: {
      MetaKey: "table-get-btn",
      CodeSuffix: "Get",
      DefaultTextVal: "详情",
    },
  },
};

const allowCustomizeResourceApiConfigKeys = [
  "resourceUrlKeyAlias",
  "childrenKeyAlia",
  "realPageFileKeyAlias",
  "resourceTypeKeyAlias",
  "resourcePermsKeyAlias",
  "resourceNameAlias",
  "resourceIconAlias",
  //"targetKeyAlias",
  //"targetResourcePermsKeyAlias",
  "idKeyAlias",
  "pidKeyAlias",
  "kebabPidAlias",
  "hasChildrenAlias",
  "kebabHasChildrenAlias",
  "ordinalKeyAlias",
  "isEnableKeyAlias",
  "kebabIsEnableKeyAlias",
  "uiOptionsKeyAlias",
];
const needKebabKeys = ["pidKeyAlias", "hasChildrenAlias", "isEnableKeyAlias"];
type ResourceType = "Menu" | "Page" | "Button";
//初始化速搭全局配置
export const initAccBuildConfig = (
  config = {
    app: null,
    GdHackDynmicComp: null,
    resourceApiAlias: {
      resourceUrlKeyAlias: "route", // 地址栏显示的路径//route
      childrenKeyAlia: "children", // 树形的子成员数组的key//children
      realPageFileKeyAlias: "pagePath", // 用于映射真实页面文件的key//pagePath
      resourceTypeKeyAlias: "resourceType", // 资源类型的key//resourceType
      resourcePermsKeyAlias: "code", // 权限代码的key//code
      resourceNameAlias: "name",
      resourceIconAlias: "icon",
      targetKeyAlias: "target", //按钮是弹窗、新页面(_blank)
      targetResourcePermsKeyAlias: "targetResourcePermsCode", //跳转目标的权限code
      idKeyAlias: "id",
      pidKeyAlias: "parentId", // kebabPidAlias必须与pidKeyAlias对应
      hasChildrenAlias: "hasChildren", // 后端返回的树形数据中不能使用,仅用于前端懒加载
      ordinalKeyAlias: "ordinal", //资源数组拼接树时排序使用
      isEnableKeyAlias: "isEnable",
      uiOptionsKeyAlias: "uiOptions",
      /* uiOptions里面的属性 */
      pageUiTemplateConfigsKeyAlias: "pageUiTemplateConfigs",
      pageLayoutConfigKeyAlias: "pageLayoutConfig",
    },
    resourcePermsKeyDefinedRule: {
      namedType: "Pascal",
      splitStr: ".",
      //内建按钮信息
      buildInBtnInfo: {
        //添加按钮
        Create: {
          MetaKey: "form-create-above-table", //按钮组件的元数据key
          CodeSuffix: "Create", //Code后缀
          DefaultTextVal: "新增",
        },
        //添加子节点
        CreateChildNode: {
          MetaKey: "table-create-child-node-btn", //按钮组件的元数据key
          CodeSuffix: "CreateChildNode", //Code后缀
          DefaultTextVal: "添加子节点",
        },
        //批量删除
        BatchDelete: {
          MetaKey: "form-batch-delete-above-table",
          CodeSuffix: "BatchDelete",
          DefaultTextVal: "批量删除",
        },
        //表格上方的查询按钮
        Search: {
          MetaKey: "form-get-list-above-table",
          CodeSuffix: "GetList",
          DefaultTextVal: "查询",
        },
        //单行删除
        Delete: {
          MetaKey: "table-delete-btn",
          CodeSuffix: "Delete",
          DefaultTextVal: "删除",
        },
        //单行编辑
        Update: {
          MetaKey: "table-update-btn",
          CodeSuffix: "Update",
          DefaultTextVal: "编辑",
        },
        //单行查看详情
        GetInfo: {
          MetaKey: "table-get-btn",
          CodeSuffix: "Get",
          DefaultTextVal: "详情",
        },
      },
    },
    routerView: {},
    global: {},
  }
) => {
  config.resourceApiAlias &&
    Object.keys(config.resourceApiAlias)
      .filter((key) => typeof key === "string" && key !== "" && allowCustomizeResourceApiConfigKeys.includes(key))
      .forEach((key) => {
        resourceApiAliasConfig[key] = config.resourceApiAlias[key];
        if (needKebabKeys.includes(key)) {
          const kebabKey = `kebab${transName(key, "Camel", "Pascal")}`;
          const kebabVal = transName(config.resourceApiAlias[key], "Camel", "Kebab");
          resourceApiAliasConfig[kebabKey] = kebabVal;
        }
      });

  config.routerView &&
    Object.keys(config.routerView).forEach((key) => {
      routerViewConfig[key] = config.routerView[key];
    });

  config.global &&
    Object.keys(config.global).forEach((key) => {
      globalConfig[key] = config.global[key];
    });
  globalConfig["compService"] = compService;
  if (globalConfig.targetPlatform !== "mobile" && config.app) {
  }
  //////
  import(`../ui-lib-plugins/${globalConfig.targetPlatform}/index.js`).then((res) => {
    res.AccBuildPlugin.install(config.app);
  });
  config.GdHackDynmicComp && (config.app as unknown as App).component("GdHackDynmicComp", config.GdHackDynmicComp);
};

export const getResourcePermsKeyInfo = (resourcePermsKey: any) => {
  if (typeof resourcePermsKey !== "string") {
    return null;
  }
  const splitStr = resourcePermsKey.charCodeAt(0) < 97 ? "." : ":";
  return {
    partialKeys: resourcePermsKey.split(splitStr),
    splitStr,
  };
};
/**
 * realPageFileKey 由多个部分组合而成;是url地址的一部分;可用于前端自定义代码的文件路径
 * 获取部分 realPageFileKey 有两种策略: Sys.User 、 sys:user
 */
export const generatePartialRealPageFileKeyStrategy = (resourcePermsKey: any) => {
  const info = getResourcePermsKeyInfo(resourcePermsKey);
  console.log(info, "---info");
  if (info) {
    return "";
  } else {
    return info!.partialKeys.pop();
  }
};

/**
 * 解决三级以上页面不能跳转问题
 *  */
export const hackSuffixJumpStr = "_JUMP";

/**
 * target的类型:_tab、_blank
 */
export const getJumpTargetVal = (resource: Object) => {
  return resource?.[resourceApiAliasConfig["uiOptionsKeyAlias"]]?.[resourceApiAliasConfig["targetKeyAlias"]] ?? "";
};

/**
 * 跳转到目标资源权限code
 */
export const getJumpTargetReourcePermsKey = (resource: Object) => {
  return resource?.[resourceApiAliasConfig["uiOptionsKeyAlias"]]?.[
    resourceApiAliasConfig["targetResourcePermsKeyAlias"]
  ];
};

/**
 * 将mapToRealPageUrl里面的部分url补全
 *  */
export const getCompleteUrl = ({
  urlInMapKeyToRealPageUrl,
  hasPrefixSlash = false,
  realPageKey,
}: {
  urlInMapKeyToRealPageUrl: String;
  hasPrefixSlash: Boolean;
  realPageKey: String;
}): String => {
  /* if (urlInMapKeyToRealPageUrl) {
        return `${hasPrefixSlash ? "/" : ""}pages${urlInMapKeyToRealPageUrl}/index`
    } else  */ if (realPageKey) {
    return `${hasPrefixSlash ? "/" : ""}pages/${realPageKey}/index`;
  } else {
    return "";
  }
};
/**
 * 根据规律获取页面的key,需要对应真实的页面文件
 */
export const realPageFilePathKeyFuc = (
  code: String,
  depth: number = 3,
  resourceType: ResourceType = "Page"
): String => {
  let arr = code
    .split(resourcePermsKeyDefinedRule.splitStr)
    .reverse()
    .filter((el, idx) => idx <= depth);
  // hack后端的code页面只有末尾两个表示
  if (resourceType === "Menu") {
    arr = [arr[0]];
  } else if (resourceType === "Page") {
    arr.length >= 3 ? (arr = arr.slice(0, 2)) : null;
  } else if (resourceType === "Button") {
    arr.length >= 4 ? (arr = arr.slice(0, 3)) : null;
  }

  return arr
    .reverse()
    .map((el) => transName(el, resourcePermsKeyDefinedRule.namedType, "Kebab"))
    .join("/");
};

/**
 * 写了页面的key 和 没写页面的key 分别对应的页面key
 */
export const getRealPageFileKey = (
  realPageFileKey: String,
  resourcePermsKey: String,
  resourceTypeKey: ResourceType,
  depth = 3
) => {
  if (realPageFileKey) {
    //后端传了真实页面文件地址
    return realPageFileKey;
  } else {
    //后端又没传真实页面文件地址,前端这个地址又没配置地址
    return realPageFilePathKeyFuc(resourcePermsKey, depth, resourceTypeKey);
  }
};
interface IndividualPageRule {
  conditionFuc: (code: String) => Boolean;
  realPageFilePathKeyFuc: (code: String, depth: number, resourceType: ResourceType) => String;
  [propname: string]: any;
}
/**
 * 判定 单独定制页面的条件
 */
export const judgeIndividualPageRule = (item: any, depth: number) => {
  const resourcePermsKeyAlias = resourceApiAliasConfig["resourcePermsKeyAlias"];
  const resourceTypeKeyAlias = resourceApiAliasConfig["resourceTypeKeyAlias"];
  /** 所有单独定制页面的条件、返回realPage值 */
  const allIndividualPageRule: Array<IndividualPageRule> = [
    /* {
          conditionFuc: (code) => code.endsWith('.SnSearch'),
          // realPageFilePathKeyFuc 可以不写,不写则按code和depth规则转换;如 三级菜单点开的页面: code="···.AbTc.BbTc.CbTc" -----对应代码页面-----> src/views/ab-tc/bb-tc/cc-tc/index.vue
          realPageFilePathKeyFuc: (code, depth) => {
            return 'sn-search';
          }
        },
        {
          // Spc目录下的所有页面,不包括Spc目录
          conditionFuc: (code) => code.split('.').pop().startsWith('Spc') && !code.split('.').pop().endsWith('Spc'),
          realPageFilePathKeyFuc: (code, depth) => {
            return 'spc';
          }
        } */
  ];
  let isMatch = false;
  let realPageFilePathKey = null;
  if (typeof item[resourcePermsKeyAlias] === "string") {
    const matchEl = allIndividualPageRule.find((el) => el.conditionFuc(item[resourcePermsKeyAlias]));
    if (matchEl) {
      isMatch = true;
      realPageFilePathKey = !matchEl.hasOwnProperty("realPageFilePathKeyFuc")
        ? realPageFilePathKeyFuc(item[resourcePermsKeyAlias], depth, item[resourceTypeKeyAlias])
        : matchEl.realPageFilePathKeyFuc(item[resourcePermsKeyAlias], depth, item[resourceTypeKeyAlias]);
    }
  }
  return {
    isMatch,
    realPageFilePathKey,
  };
};

/**
 * 获取页面资源的VmCode;也就是resourcePermCode的最后一个单词
 */
export const getCurResourceLastCode = (resource: Object, toNamingRule = "Pascal") => {
  const resourcePermsKeyAlias = resourceApiAliasConfig["resourcePermsKeyAlias"];

  const vmCode =
    typeof resource[resourcePermsKeyAlias] === "string" &&
    resource[resourcePermsKeyAlias].split(resourcePermsKeyDefinedRule.splitStr).pop();
  if (toNamingRule === "Pascal") {
    return vmCode;
  } else {
    return transName(vmCode, "Pascal", "Kebab");
  }
};

/////////////////////////////////////////////
//资源ui相关非空取值;

//////////////////////////////////////////
export const getPageUiTemplateConfigs = (pageResource: Object) => {
  const uiOptionsKeyAlias = resourceApiAliasConfig["uiOptionsKeyAlias"];
  const pageUiTemplateConfigsKeyAlias = resourceApiAliasConfig["pageUiTemplateConfigsKeyAlias"];
  return pageResource[uiOptionsKeyAlias]?.[pageUiTemplateConfigsKeyAlias] ?? [];
};

export const getPageUiTemplatepageLayoutConfig = (pageResource: Object) => {
  const uiOptionsKeyAlias = resourceApiAliasConfig["uiOptionsKeyAlias"];
  const pageLayoutConfigKeyAlias = resourceApiAliasConfig["pageLayoutConfigKeyAlias"];
  return pageResource[uiOptionsKeyAlias]?.[pageLayoutConfigKeyAlias] ?? {};
};
